home *** CD-ROM | disk | FTP | other *** search
-
- /************************************************************************/
-
- /* File KUTIL2.C - Extended buffer filling/emptying procedures etc.
- Chris Kennington RML. 9th July 1985 */
-
- #define DEFS1 1
- #define DEFS3 1
- #define DEFS4 1
-
- #include "stdio.h"
- #include "ctype.h"
- #include "b:kext.h"
-
- /* Variables global to this file:- */
-
- static int oldsz, oldt, qu8=0, rpt, sz;
- static char *dt;
- static char del1[] = {BKSP,SP,0};
- static char del7[] = {BKSP,BKSP,BKSP,BKSP,BKSP,BKSP,BKSP,SP,SP,SP,SP,SP,SP,SP,0};
- #ifndef MPUZ80
- static char *images[] = {"7-bit stripped","8-bit binary","8th-bit prefixed",0};
- #endif
-
- extern int outfc(), outfile();
-
-
-
- char ascch(c) /* edit out multiple CR/LFs */
- /* Returns c unless redundant, when returns 0 */
- char c;
- {
- static char oldc = 0;
-
- c &= 0x7f; /* strip to 7 bits */
- if ( ( (c == CR) && (oldc == LF) ) || ( (c == LF) && (oldc == CR) ) )
- c = oldc = 0;
- else {
- oldc = c;
- if (c == LF)
- c = CR;
- }
- return(c);
- } /* end of ascch() */
-
-
-
- bufemp(buffer,len)
- /* Puts data from an incoming packet into a file,
- sleeping & waking comms & network.
- If no file open (fp = 0), displays on screen
- Returns 0 if OK, else contents of "errno". */
- char buffer[]; /* Buffer */
- int len;
- {
- int ret;
-
- if (fp == 0)
- ret = decode(buffer,len,outfc);
- else {
- s4sleep(); /* Inhibit communications */
- if (list == 1)
- outc('.');
- ret = decode(buffer,len,outfile);
- }
- netcool();
- return(ret);
- } /* end of bufemp() */
-
-
-
- bufill(buffer)
- /* Get a bufferful of data from the file that's being sent, sleeping
- * & waking comms & network.
- * Traps CP/M soft EoF (ctl-Z). */
- char *buffer;
- {
- int t;
-
- s4sleep(); /* Inhibit communications */
- errno = 0;
- dt = buffer;
- if (softeof) { /* Trap CP/M text-file */
- sz = EOF;
- goto Exit;
- }
- if (list == 1)
- outc('.'); /* dot-printing */
- rpt = sz = 0; /* Init data buffer pointer */
- oldt = -2; /* impossible value */
- while((t = getc(fp)) != EOF) { /* Get the next character */
- /* if there is an error, getc() will also return EOF and there is an
- error-code in "errno". This is picked up in sdata(). */
- #ifdef MPUZ80
- if (list == 2)
- #else
- if ( (list == 2) && (t != LF) )
- #endif
- outc(t);
- encode(t);
- if ( (image == 0) && (t == CTLZ) ) {
- softeof = TRUE;
- goto Exit; /* CP/M text EOF */
- }
- if (sz > spsiz-7) /* Check length */
- goto Exit;
- }
- /* reach here on (hard) EOF or error */
- softeof = TRUE; /* so dont reread */
- if (sz==0)
- sz = EOF;
- Exit:
- netcool();
- return(sz); /* Handle partial buffer */
- } /* end of bufill() */
-
-
-
- clear5() /* clear bottom lines of screen */
- {
- int lin;
-
- lin = (SCRBOT+3)*256;
- while (lin < (SCRLEN*256)) {
- vtline(lin,blanx);
- lin += 256;
- }
- } /* end of clear5() */
-
-
-
- compmode() /* display transfer modes */
- {
- if (image == 2)
- txtout(" 8-bit data, ");
- else if (oldimage == 2) {
- printmsg("Warning: 8-bit transfer not agreed by remote Kermit.\r");
- oldimage = image;
- }
- if (rptflg == TRUE)
- txtout(" Compressing, ");
- return;
- } /* end of compmode() */
-
-
-
- decode(buf,len,fn) /* packet decoding procedure */
- /* Called with string to be decoded and an output function.
- Returns 0 or error-code. */
- char *buf;
- int len, (*fn)();
- {
- char a, a7, b8, *end, rep;
- int flg8=0, r, rr=0;
-
- if (image == 2)
- flg8 = -1;
-
- end = buf + len;
- while (buf < end) {
- a = *buf++;
- if ( rptflg && (a == '~') ) { /* got a repeat prefix? */
- rep = unchar(*buf++); /* Yes, get the repeat count, */
- a = *buf++; /* and get the prefixed character. */
- }
- else
- rep = 1;
- b8 = 0; /* Check high order "8th" bit */
- if ( flg8 && (a == qu8) ) {
- b8 = 0200;
- a = *buf++; /* and get the prefixed character. */
- }
- if (a == quote) { /* If control prefix, */
- a = *buf++; /* get its operand. */
- a7 = a & 0177; /* Only look at low 7 bits. */
- if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') /* Uncontrollify */
- a = ctl(a); /* if in control range. */
- }
- a |= b8; /* OR in the 8th bit */
- while (rep-- > 0) {
- r = (*fn)(a); /* Send them to the output function. */
- rr |= r;
- } }
- return(rr);
- } /* end of decode() */
-
-
-
- encode(a)
- /* encode single character into packet for transmission */
- int a; /* char to be encoded */
- {
- int a7; /* Low order 7 bits */
- int b8; /* 8th bit of character */
- int flg8 = 0;
-
- if (image == 2)
- flg8 = -1;
-
- if (rptflg) { /* repeat-count processing */
- if (a == oldt) { /* char is same */
- /* This algorithm is simple but relatively inefficient; it stores
- the repeat flag, count and character each time around so
- that when the run is broken the buffer is valid; also it
- treats a pair as a run, which requires 3 bytes not 2 unless
- the pair is control- or 8bit-prefixed; but it does not
- require lookahead logic from the data-read. */
- sz = oldsz; /* wind back pointer */
- dt[sz++] = '~'; /* store prefix */
- dt[sz++] = tochar(++rpt); /* & count */
- if (rpt > 93) /* force new start */
- oldt = -2; /* impossible value */
- }
- else { /* not run, or end */
- rpt = 1;
- oldt = a; /* save char */
- oldsz = sz;
- } }
-
- a7 = a & 0177; /* Isolate ASCII part */
- b8 = a & 0200; /* and 8th (parity) bit. */
-
- if (flg8 && b8) { /* Do 8th bit prefix if necessary. */
- dt[sz++] = qu8;
- a = a7;
- }
- if ((a7 < SP) || (a7==DELT)) { /* Do control prefix if necessary */
- dt[sz++] = MYQUOTE;
- a = ctl(a);
- }
- if (a7 == MYQUOTE) /* Prefix the control prefix */
- dt[sz++] = MYQUOTE;
- else if (rptflg && (a7 == '~')) /* If it's the repeat prefix, */
- dt[sz++] = MYQUOTE; /* quote it if doing repeat counts. */
- else if (flg8 && (a7 == qu8)) /* Prefix the 8th bit prefix */
- dt[sz++] = MYQUOTE; /* if doing 8th-bit prefixes */
-
- dt[sz++] = a; /* Finally, insert the character */
- dt[sz] = '\0'; /* itself, and mark the end. */
- return;
- } /* end of encode() */
-
-
-
-
- error(fmt, a1, a2, a3, a4, a5)
- /* Generate both error-message to user and if suitable
- error-packet to remote. */
- char *fmt;
- {
- int len;
-
- sprintf(packet,fmt,a1,a2,a3,a4,a5);
- printmsg(packet);
- if ( (kmode == RECV) || (kmode == SEND) ) {
- len = strlen(packet) + 1;
- spack('E',n,len,packet);
- }
- return;
- } /* end of error() */
-
-
-
-
- /* kropen(), kwopen(), kclose():
- Open and close CP/M files making necessary calls to sleep
- and wake disk system & network. */
-
- kclose(fptr) /* close file */
- FILE *fptr;
- {
- int ret;
-
- if (fptr == 0)
- return;
- bell();
- ++files;
- s4sleep();
- if ( (ret = fclose(fptr)) < 0)
- printmsg(diskfail,errno); /* Aztec's error-code */
- else
- ret = 0;
- netcool();
- return(ret);
- } /* end of kclose() */
-
-
- FILE *kropen(name) /* open file for reading */
- char name[];
- {
- FILE *frp;
-
- s4sleep();
- softeof = FALSE;
- frp = fopen(name,"r");
- netcool();
- return(frp);
- } /* end of fropen() */
-
-
- FILE *kwopen(name) /* open file for writing */
- char *name;
- {
- FILE *frp;
-
- s4sleep();
- frp = fopen(name,"w");
- netcool();
- return(frp);
- } /* end of kwopen() */
-
- /* end of open-&-close routines */
-
-
-
- no_op() /* null routine */
- {
- return;
- } /* End of no_op() */
-
-
-
- outfc(ch) /* output char with control */
- char ch;
- /* expands tabs (every 8) and handles paging;
- returns 1 if CTLC input at CR or LF, else 0. */
- {
- static char col=0;
- char c, *more, *dlt;
-
- if (ch < SP) switch(ch) {
- /* deal with selected control-characters */
- case CR:
- if (kbdin() == CTLC)
- return(1);
- if (pager != 0)
- if ( ++scrline > (pager << 2) ) {
- if (col < 73) { /* room for "[more]" */
- while (col++ < 73)
- outc(SP);
- more = "[more]";
- while ( (c = *more++) != 0)
- outc(c);
- dlt = del7;
- }
- else if (col < 79) { /* no room */
- while (col++ < 78)
- outc(SP);
- outc('*');
- dlt = del1;
- }
- else
- dlt = null;
- if ( (commode & 0x02) != 0 )
- nextout(XOFF); /* hold up */
- while ( (c = kbdin()) == 0)
- ;
- if ( (commode & 0x02) != 0 )
- nextout(XON); /* restart */
- scrline = 0;
- if (c == CTLC)
- return(1);
- while ( (c = *dlt++) != 0)
- outc(c);
- }
- outc(ch);
- col = 0;
- break;
-
- case LF:
- /* ignored - CR is expected to be treated as "newline" */
- break;
-
- case TAB:
- c = 8 - (col & (char)0x07);
- col &= (char)0xf8;
- col += 0x08;
- while (c-- > 0)
- outc(SP);
- break;
-
- case BKSP:
- if (col-- < 0)
- col = 0;
- else
- outc(BKSP);
- break;
-
- default: /* pass all other controls */
- outc(ch);
- break;
- } /* end if-switch */
- else { /* normal chars */
- outc(ch);
- ++col;
- }
- return(0);
- } /* end of outfc() */
-
-
-
-
- static int outfile(ch) /* char to file */
- /* Returns 0 or error-code */
- char ch;
- {
- int r;
-
- r = errno = 0;
- if (image == 0) /* for 7-bit transfers */
- if ( (ch = ascch(ch)) == 0 ) /* CR/LF trapping */
- return(0); /* ignore nulls */
- else if (ch == CR) { /* CR => CR/LF */
- putc(CR,fp);
- if (list == 2)
- outc(CR);
- ch = LF;
- } /* end elseif */
- #ifndef MPUZ80
- if ( (list == 2) && (ch != LF) )
- #else
- if (list == 2)
- #endif
- outc(ch);
- if (putc(ch,fp) < 0)
- r = errno; /* accumulate errors */
- return(r);
- } /* end of outfile() */
-
-
-
- parex() /* exchange parameters */
- /* returns 1 if successful, -1 if refused, 0 if no answer;
- only allows 3 timeouts/NAKs */
- {
- int ln1, ln2, num, r=0, t;
-
- ln1 = spar(packet); /* fill with ours */
- forever {
- spack('I',0,ln1,packet);
- switch( (t = rpack(&ln2,&num,recpkt)) ) {
- case 'Y': /* ACK */
- rpar(recpkt,ln2); /* take theirs */
- txtout(" OK ");
- compmode();
- n = num + 1; /* initial number */
- return(1);
- case 'N': /* NAK */
- case FALSE: /* timeout */
- if (r++ > 3)
- return(0);
- else
- break;
- default: /* protocl error */
- printmsg(badmsg,'Y',t);
- case 'E': /* cant cope */
- return(-1);
- } /* end switch */
- txtout(trying);
- } /* end forever */
- } /* end of parex() */
-
-
-
- rpar(data,len) /* instal received parameters safely */
- char *data, len;
- /* Set up incoming parameters to either what has been received
- or, if nil, to defaults.
- RML Kermit does not handle variable timeouts.
- No return-code. */
- {
- char i, p;
-
- /* initialize to defaults in case incoming block is short */
- spsiz = 80; /* packet-length 80 chars */
- eol = CR; /* terminator normally CR */
- quote = '#'; /* standard control-quote char */
- qu8 = 0; /* no 8th-bit quoting */
- rptflg = 0; /* nor repeat-quoting */
- /* image is not changed */
-
- i = 0;
- while (len-- > 0) {
- p = data[len];
-
- switch (len) { /* for each parameter */
-
- case 0: /* MAXL */
- spsiz = unchar(p);
- break;
-
- case 2: /* NPAD */
- pad = unchar(p);
- break;
-
- case 3: /* PADC */
- padchar = ctl(p);
- break;
-
- case 4: /* EOL */
- eol = unchar(p);
- break;
-
- case 5: /* QCTL */
- quote = p;
- break;
-
- case 6: /* QBIN */
- /* 8th-bit quoting only negotiable if set by user */
- i = 1;
- if (image == 2) switch (p) {
- case 'Y':
- qu8 = '&';
- break;
- case 'N':
- qu8 = image = 0;
- break;
- default:
- if (isalnum(p) == 0) /* provided punctuation */
- qu8 = p;
- else
- qu8 = image = 0;
- break;
- } /* end inner switch */
- break;
-
- case 8: /* REPT */
- if (p == '~')
- rptflg = TRUE;
- break;
-
- default: /* CHKT, CAPAS etc. */
- break;
-
- } } /* end while & outer switch */
-
- if (i == 0) /* no data[6] */
- qu8 = 0;
- if ( (qu8 == 0) && (image == 2) ) /* invlaid setting */
- image = 0;
- if (list > 2) { /* debug only */
- printf("\rDbg: Parameters in, 8th-bit setting now %d ",image);
- #ifndef MPUZ80
- printf("(%s)",images[image]);
- if (image == 2)
- printf(", prefix %c. ",qu8);
- else
- printf(". ");
- #endif
- }
- return;
- } /* end of rpar() */
-
-
-
-
- show5(text)
- /* display up to 5 lines of text at bottom of screen */
- char **text;
- {
- char c, *hp;
- int lin;
-
- clear5(); /* clear it first */
- lin = (SCRBOT+3)*256;
- for (c=0; c<5; ++c) {
- if ( (hp = text[c]) == 0 )
- break;
- vtline(lin,hp);
- if ( (lin += 256) > 24*256)
- break;
- }
- return;
- } /* end of show5() */
-
-
-
- spar(data) /* fill up packet with own parameters */
- char *data;
- /* returns length of parameter block (6, 7 or 9) */
- {
- char len;
-
- data[0] = tochar(spsiz);
- data[1] = tochar(MYTIME);
- data[2] = tochar(MYPAD);
- data[3] = ctl(0);
- data[4] = tochar(MYEOL);
- data[5] = MYQUOTE;
- len = 6; /* min length */
- if (image == 2) {
- data[6] = 'Y'; /* feed back 8-quote */
- if (qu8 == 0)
- qu8 = '&';
- len = 7;
- }
- else {
- data[6] = 'N'; /* otherwise reject */
- qu8 = 0;
- }
- if (rptflg) { /* if repeat-quoting */
- data[7] = '1'; /* 1-byte checksum */
- data[8] = '~'; /* only ~ for repeating*/
- len = 9;
- }
- if (list > 2) { /* debug only */
- printf("\rDbg: Parameters out, 8th-bit setting now %d ",image);
- #ifndef MPUZ80
- printf("(%s)",images[image]);
- if (image == 2)
- printf(", prefix %c. ",qu8);
- else
- printf(". ");
- #endif
- }
- return(len);
- } /* end of spar() */
-
-
-
- /********************** End of KUTIL2.C **************************/
-